@astrale-domains/issues 0.1.2 → 0.1.3

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.
Files changed (71) hide show
  1. package/CHANGELOG.md +69 -0
  2. package/README.md +71 -15
  3. package/dist/schema/.runtime/states/issue/index.d.ts +30 -0
  4. package/dist/schema/.runtime/states/issue/index.js +11 -0
  5. package/dist/schema/comment/class.d.ts +35 -3
  6. package/dist/schema/comment/class.js +11 -2
  7. package/dist/schema/comment/contribute-to-comment-policy.d.ts +1 -0
  8. package/dist/schema/comment/contribute-to-comment-policy.js +12 -0
  9. package/dist/schema/comment/edit-own-comment-policy.d.ts +1 -0
  10. package/dist/schema/comment/edit-own-comment-policy.js +6 -0
  11. package/dist/schema/comment/index.d.ts +3 -0
  12. package/dist/schema/comment/index.js +3 -0
  13. package/dist/schema/comment/methods.js +18 -0
  14. package/dist/schema/comment/relationships.d.ts +4 -4
  15. package/dist/schema/comment/relationships.js +10 -5
  16. package/dist/schema/comment/traverse-comment-relationship-policy.d.ts +2 -0
  17. package/dist/schema/comment/traverse-comment-relationship-policy.js +17 -0
  18. package/dist/schema/index.d.ts +5 -6
  19. package/dist/schema/index.js +4 -5
  20. package/dist/schema/issue/class.d.ts +163 -4
  21. package/dist/schema/issue/class.js +21 -9
  22. package/dist/schema/issue/contribute-to-issue-policy.d.ts +1 -0
  23. package/dist/schema/issue/contribute-to-issue-policy.js +10 -0
  24. package/dist/schema/issue/index.d.ts +3 -1
  25. package/dist/schema/issue/index.js +3 -1
  26. package/dist/schema/issue/methods.js +66 -0
  27. package/dist/schema/issue/relationships.d.ts +15 -60
  28. package/dist/schema/issue/relationships.js +21 -15
  29. package/dist/schema/issue/traverse-issue-relationship-policy.d.ts +5 -0
  30. package/dist/schema/issue/traverse-issue-relationship-policy.js +55 -0
  31. package/dist/schema/project/class.d.ts +234 -0
  32. package/dist/schema/project/class.js +27 -0
  33. package/dist/schema/project/contribute-to-project-policy.d.ts +1 -0
  34. package/dist/schema/project/contribute-to-project-policy.js +6 -0
  35. package/dist/schema/project/index.d.ts +5 -0
  36. package/dist/schema/project/index.js +5 -0
  37. package/dist/schema/project/manage-project-policy.d.ts +1 -0
  38. package/dist/schema/project/manage-project-policy.js +6 -0
  39. package/dist/schema/project/methods.js +68 -0
  40. package/dist/schema/{command → project}/relationships.d.ts +9 -9
  41. package/dist/schema/project/relationships.js +15 -0
  42. package/dist/schema/project/traverse-project-relationship-policy.d.ts +4 -0
  43. package/dist/schema/project/traverse-project-relationship-policy.js +20 -0
  44. package/dist/schema/{application/index.d.ts → schema.d.ts} +454 -335
  45. package/dist/schema/schema.js +44 -0
  46. package/dist/schema/tag/class.d.ts +39 -2
  47. package/dist/schema/tag/class.js +6 -1
  48. package/dist/schema/tag/contribute-to-tag-policy.d.ts +1 -0
  49. package/dist/schema/tag/contribute-to-tag-policy.js +10 -0
  50. package/dist/schema/tag/index.d.ts +3 -1
  51. package/dist/schema/tag/index.js +3 -1
  52. package/dist/schema/tag/manage-tag-policy.d.ts +1 -0
  53. package/dist/schema/tag/manage-tag-policy.js +10 -0
  54. package/dist/schema/tag/methods.js +21 -0
  55. package/dist/schema/tag/relationships.d.ts +2 -2
  56. package/dist/schema/tag/relationships.js +11 -7
  57. package/dist/schema/value/index.js +34 -0
  58. package/package.json +16 -6
  59. package/dist/schema/application/functions.js +0 -156
  60. package/dist/schema/application/index.js +0 -49
  61. package/dist/schema/command/class.d.ts +0 -38
  62. package/dist/schema/command/class.js +0 -13
  63. package/dist/schema/command/index.d.ts +0 -2
  64. package/dist/schema/command/index.js +0 -2
  65. package/dist/schema/command/relationships.js +0 -14
  66. package/dist/schema/tracker/class.d.ts +0 -73
  67. package/dist/schema/tracker/class.js +0 -10
  68. package/dist/schema/tracker/index.d.ts +0 -2
  69. package/dist/schema/tracker/index.js +0 -2
  70. package/dist/schema/tracker/relationships.d.ts +0 -16
  71. package/dist/schema/tracker/relationships.js +0 -7
package/CHANGELOG.md ADDED
@@ -0,0 +1,69 @@
1
+ # Changelog
2
+
3
+ ## [0.1.3](https://github.com/astrale-os/domains/compare/issues-v0.1.2...issues-v0.1.3) (2026-08-27)
4
+
5
+
6
+ ### Features
7
+
8
+ * **issues:** replace Tracker with collaborative Projects ([#93](https://github.com/astrale-os/domains/issues/93)) ([68fbabe](https://github.com/astrale-os/domains/commit/68fbabe10ce1ffe45f854166c6db1a7028a10759))
9
+ * make Domain lifecycles authoritative ([#101](https://github.com/astrale-os/domains/issues/101)) ([4ed45f6](https://github.com/astrale-os/domains/commit/4ed45f6c3f5708db52455904c28a2c13c983e33f))
10
+
11
+ ## [0.1.2](https://github.com/astrale-os/domains/compare/issues-v0.1.1...issues-v0.1.2) (2026-08-26)
12
+
13
+
14
+ ### Features
15
+
16
+ * **domains:** complete AI Gateway and Integrations parity qualification ([#87](https://github.com/astrale-os/domains/issues/87)) ([5be7461](https://github.com/astrale-os/domains/commit/5be74610469c4a20b108d73c38d0d2b6a298eef6))
17
+ * **domains:** restore AI Gateway and Integrations parity ([#80](https://github.com/astrale-os/domains/issues/80)) ([51ca802](https://github.com/astrale-os/domains/commit/51ca8027109bdc3fd3a05e861e6ed58bea8fe755))
18
+
19
+
20
+ ### Bug Fixes
21
+
22
+ * align domains with current SDK cohort ([#85](https://github.com/astrale-os/domains/issues/85)) ([f2153e2](https://github.com/astrale-os/domains/commit/f2153e271e1389692ee9f98a14207c5e4340a743))
23
+ * **deps:** qualify GRC and domain dependencies ([#84](https://github.com/astrale-os/domains/issues/84)) ([e8a4c6b](https://github.com/astrale-os/domains/commit/e8a4c6b80e8e8f02a385e0001aa0f220acef5ce6))
24
+
25
+ ## [0.1.1](https://github.com/astrale-os/domains/compare/issues-v0.1.0...issues-v0.1.1) (2026-08-25)
26
+
27
+
28
+ ### Features
29
+
30
+ * **events:** add Events V0 and async issue notifications ([9538769](https://github.com/astrale-os/domains/commit/9538769b0e3ff4063583b3798b1e2301098a5e0c))
31
+ * **issues:** add complete issues domain ([9b9928c](https://github.com/astrale-os/domains/commit/9b9928cea40d91db91083935ee074086d8d365bd))
32
+ * **issues:** polish scoped views and navigation ([8c67e56](https://github.com/astrale-os/domains/commit/8c67e56ef273054b9ea82e852bbe1d5f32f05ca5))
33
+ * **issues:** publish creation events asynchronously ([711a2ec](https://github.com/astrale-os/domains/commit/711a2eceb7b12d2a24db7051bb6a4a9ea5bc8601))
34
+ * **issues:** publish schema package ([cf931cb](https://github.com/astrale-os/domains/commit/cf931cb50efe2e9888b8721dc7d7876aaf39d05e))
35
+ * **issues:** support priority updates ([2ade78d](https://github.com/astrale-os/domains/commit/2ade78dd46f91c8dd6d170edc2fc5c03aa9ccbb3))
36
+ * overhaul domain apps and runtime flows ([cb92e06](https://github.com/astrale-os/domains/commit/cb92e0601d329a601c4eb072d4c80b0eff6816e7))
37
+ * overhaul services and domain applications ([b8bc24d](https://github.com/astrale-os/domains/commit/b8bc24dbce4c4541ccf1f453b5f3cd335ff1aca4))
38
+ * publish Schema-only Domain contracts ([ec0a16a](https://github.com/astrale-os/domains/commit/ec0a16a46a08a3a2118ca1490a4f7e71239d62eb))
39
+ * publish Schema-only Domain contracts ([70aab15](https://github.com/astrale-os/domains/commit/70aab152f4eea0c69fed1a35cd4611d8d2f99ff9))
40
+ * replace issues and events with kernel v2 ([c0152fa](https://github.com/astrale-os/domains/commit/c0152fa326a598cfe76bbda75f5e7cc5d42fd011))
41
+ * **skills:** add domain skill packages ([#28](https://github.com/astrale-os/domains/issues/28)) ([6c0b949](https://github.com/astrale-os/domains/commit/6c0b949f1e5821d9f53745fb02eca3453ffb7f80))
42
+
43
+
44
+ ### Bug Fixes
45
+
46
+ * **ci:** keep standalone packaging permissive ([9151cf9](https://github.com/astrale-os/domains/commit/9151cf99311dd070068734c373a1b7ec7e1027a0))
47
+ * **ci:** make domain workspace standalone ([ff42931](https://github.com/astrale-os/domains/commit/ff429317dfd8dd4b0af2ffe8160867c9ba410099))
48
+ * **ci:** simplify Domain publication ([097befc](https://github.com/astrale-os/domains/commit/097befc1217352ce4e3ce91c01d797aba8fd78a2))
49
+ * **ci:** simplify Domain publication ([1b99dd9](https://github.com/astrale-os/domains/commit/1b99dd9781337e13e63c5b1838d96d4fd0dfa3bc))
50
+ * fetch kernel packages from codeload ([c7239d3](https://github.com/astrale-os/domains/commit/c7239d3678c97c902688e42476c93f568ed523bf))
51
+ * **frontend:** complete retained Domain identity ([cd667d1](https://github.com/astrale-os/domains/commit/cd667d111da05b76c599ce60ba7d741994a40abb))
52
+ * **frontend:** complete retained Domain identity ([efb9878](https://github.com/astrale-os/domains/commit/efb9878947877205f3469836d226875a7c50d055))
53
+ * **frontend:** restore project source discovery ([#72](https://github.com/astrale-os/domains/issues/72)) ([7795508](https://github.com/astrale-os/domains/commit/77955086688833289b474c64314a6adae598be9f))
54
+ * **issues:** grant create mutation authority ([60ebffc](https://github.com/astrale-os/domains/commit/60ebffc28bda5fd3b54333d347b7375edab538f9))
55
+ * **issues:** hide migration provenance in views ([246c9a2](https://github.com/astrale-os/domains/commit/246c9a2a074cfec115177f52ce8096c7eb688f08))
56
+ * **issues:** pin a coherent kernel cohort ([2bb8f80](https://github.com/astrale-os/domains/commit/2bb8f80e872d301d0dd7c0b32ddbc0e01151a7c5))
57
+ * **issues:** pin mature frontend dependencies ([e8f67f3](https://github.com/astrale-os/domains/commit/e8f67f3ac81ad1178675bc00b0cb787dba62d183))
58
+ * **issues:** preserve complete native issue projections ([6c327e3](https://github.com/astrale-os/domains/commit/6c327e33d0c203af70f006050509856b9d67540b))
59
+ * **issues:** preserve complete paginated exports ([35d03d2](https://github.com/astrale-os/domains/commit/35d03d216ef13a07cfada894f2d93fe3ba390d89))
60
+ * **issues:** remove redundant list method ([1ca9a31](https://github.com/astrale-os/domains/commit/1ca9a31fbaead49b3b0a715a862e3751e79bbc25))
61
+ * **issues:** restore Issue.create function authority ([20f6169](https://github.com/astrale-os/domains/commit/20f6169f17b5e0922cb3108624e69a81e2765bf1))
62
+ * **issues:** use mature lucide release ([c0010f5](https://github.com/astrale-os/domains/commit/c0010f52de8c2eefbb4c6c900760c51ac18b602d))
63
+ * migrate durable domains to public invocation errors [skip ci] ([b951546](https://github.com/astrale-os/domains/commit/b95154607eabcb19b152bf6192b202c884337391))
64
+ * pin published kernel runtime beta ([d3f508e](https://github.com/astrale-os/domains/commit/d3f508e56c85b3595a56fe880f07bb34a895a906))
65
+ * require hosted-functions SDK release ([e4d3122](https://github.com/astrale-os/domains/commit/e4d312268798a1ab803b815ebaff234aae24500a))
66
+ * use HTTPS for kernel dependencies ([182c604](https://github.com/astrale-os/domains/commit/182c6045580f407d0cd42077e9d4a8286770cf3a))
67
+ * use published kernel package cohort ([6671da9](https://github.com/astrale-os/domains/commit/6671da9fc3f27f05b165da59a184ca5291e86d07))
68
+ * **views:** adopt proof-bounded Shell cohort ([#74](https://github.com/astrale-os/domains/issues/74)) ([09fb9f3](https://github.com/astrale-os/domains/commit/09fb9f39e5350cf930ff083090b6a6f21369dc49))
69
+ * **views:** retain graph query provenance ([#75](https://github.com/astrale-os/domains/issues/75)) ([c880a42](https://github.com/astrale-os/domains/commit/c880a42f78f15e24ebfe54ae4eb76388d8872a80))
package/README.md CHANGED
@@ -1,28 +1,83 @@
1
1
  # Issues Domain
2
2
 
3
- `issues.astrale.ai` owns caller-scoped Trackers, numbered Issues, Comments, Tags, Issue relations, and replay-safe command receipts.
3
+ `issues.astrale.ai` owns collaborative Projects, numbered Issues, Comments, and Project-local Tags.
4
+ It is a current Astrale Application with Schema Policies, receiver Methods, atomic Mutations, and an
5
+ inbox-first Shell View.
4
6
 
5
- This is a current Astrale Application, not the former repository/module abstraction:
7
+ ```text
8
+ Project
9
+ owned by one Identity; shared with member Identities
10
+ key, name, optional description, private owner/member execution index and nextIssueNumber, archived
11
+ contains Issues and Tags
12
+
13
+ Issue
14
+ immutable reference; title; optional description
15
+ status: open | accepted | resolved | deferred | closed
16
+ priority: 0..4; optional assignee; optional acyclic parent; Tags
17
+
18
+ Comment
19
+ body; immutable author; belongs to one Issue
20
+
21
+ Tag
22
+ name; Project-local slug; optional color; belongs to one Project
23
+ ```
24
+
25
+ The public mutation surface is receiver-owned:
6
26
 
7
27
  ```text
8
- schema/ public Classes, relationships, Functions, and application View
9
- states/ closed Issue lifecycle
10
- rules/ pure normalization, transitions, and receipt decisions
11
- queries/ named owner-scoped graph observations
12
- mutations/ atomic graph changes and receipt preconditions
13
- actions/ one-operation list handler
14
- workflows/ authorization observation, replay, and Mutation coordination
15
- views/ Shell-bound Tracker projection
16
- ui/ Domain-free presentation
17
- frontend/ Vite and TanStack Router application
28
+ Project.create
29
+ Project.update | addMember | removeMember | createIssue | createTag | archive
30
+ Issue.update | assign | setTags | setParent | addComment | archive
31
+ Comment.edit | delete
32
+ Tag.edit | delete
18
33
  ```
19
34
 
20
- Every mutation creates a `Command` receipt in the same MutationAST as its business change. The receipt key is scoped through `command_requested_by`; its mutation precondition proves the key is unused. A repeated call reads the receipt, verifies the kind and fingerprint, and returns the retained target rather than submitting the change again. Reusing a key for different input fails closed.
35
+ `Tag.delete` remains one atomic Mutation through 2,046 linked Issues, the current supported Kernel
36
+ execution ceiling after its containment and Node removals. Larger Tags must first be removed from
37
+ enough Issues through `Issue.setTags`; the Workflow rejects them explicitly instead of submitting an
38
+ oversized Mutation with a backend-dependent failure.
21
39
 
22
- The deleted Events Domain is not replaced by a fake package or hidden adapter. Issues no longer owns an Events outbox. Event publication can return later only as an explicit provider-neutral Integration with a real consumer and delivery contract.
40
+ `Project.create` requires authentication. Receiver Methods use Schema-owned Policies: Project owners
41
+ administer metadata, membership, Tags, and archival; owners and members contribute to Issues; only a
42
+ Comment author edits or deletes it. Reads are visible only through a Project the caller owns or has
43
+ joined.
44
+
45
+ Ownership, membership, reporting, assignment, and authorship remain graph-native Policy facts. The
46
+ owning Project, Issue, or Comment also stores the corresponding Identity IDs privately, updated in
47
+ the same atomic Mutation as each edge. Recipes and Workflows can therefore validate current collaboration state
48
+ without requesting authority over every possible concrete Identity subtype from another Domain.
49
+ Those private execution fields are not a second public model and never replace the Policy edges.
50
+
51
+ There is no Domain `Command`, receipt, universal idempotency layer, activity log, or undo system.
52
+ `Project.create` is one Action; the sixteen multi-step receiver operations are explicit Workflows
53
+ whose Query and Mutation effects use stable steps. Set-style changes converge naturally and stale
54
+ concurrent writes reject through atomic Mutation preconditions. Creation retries have no Domain
55
+ replay guarantee; generic invocation idempotency belongs to the platform when it exists.
56
+
57
+ The mounted View defaults to a focused open-Issue Inbox with queue progress and keyboard or button
58
+ navigation. Accepted work has a dedicated discussion view, while Browse searches and filters the
59
+ complete visible corpus with bounded pagination. The roomy metadata drawer exposes Close, Defer,
60
+ Resolved, and Accept triage actions plus priority, assignment, Tags, and parent controls without
61
+ blurring the main view. The four outcomes display and honor the `C`, `D`, `R`, and `A` keyboard
62
+ shortcuts whenever the user is not typing. The selected Issue description and its Comment thread remain below the
63
+ inbox as one continuous Markdown conversation with strict Mermaid diagrams. Project, Issue, and Tag
64
+ creation and Project membership administration intentionally remain API-first.
65
+
66
+ ## Breaking migration
67
+
68
+ `Tracker` to `Project`, the status revision (`in_progress` to `accepted`, `canceled` to `closed`, and
69
+ the new `deferred` outcome), receiver Methods, and Command removal are one
70
+ deliberate breaking revision. A reinstall does not migrate installed graph keys. Use the private
71
+ [legacy snapshot/import workflow](https://github.com/astrale-os/domains/tree/main/issues/scripts/legacy-issues-import)
72
+ before production cutover. It retains excluded source data for audit, deprovisions the exact
73
+ digest-confirmed legacy graph before uninstall, and replays owner-authored legacy aggregates through
74
+ the supported public Project receiver API while writing step-level old-to-new Node ID checkpoints.
23
75
 
24
76
  ## Development
25
77
 
78
+ Dependency changes must refresh both `issues/pnpm-lock.yaml` and the workspace-root `pnpm-lock.yaml`;
79
+ repository CI installs the latter with a frozen lockfile.
80
+
26
81
  ```bash
27
82
  pnpm install
28
83
  pnpm typecheck
@@ -33,4 +88,5 @@ pnpm build
33
88
  pnpm package
34
89
  ```
35
90
 
36
- Domain source imports Kernel concepts through semantic `@astrale-os/sdk/*` facades and owns no `.spec` tree.
91
+ Domain source imports Kernel concepts through semantic `@astrale-os/sdk/*` facades and owns no
92
+ `.spec` tree.
@@ -0,0 +1,30 @@
1
+ import { type EventOf, type StateOf, type TransitionDecision } from '@astrale-os/sdk/state';
2
+ export declare const issueLifecycle: import("@astrale-os/sdk/state").StateMachine<{
3
+ readonly open: {
4
+ readonly accept: "accepted";
5
+ readonly defer: "deferred";
6
+ readonly close: "closed";
7
+ };
8
+ readonly accepted: {
9
+ readonly resolve: "resolved";
10
+ readonly defer: "deferred";
11
+ readonly close: "closed";
12
+ };
13
+ readonly deferred: {
14
+ readonly reopen: "open";
15
+ readonly accept: "accepted";
16
+ readonly close: "closed";
17
+ };
18
+ readonly resolved: {
19
+ readonly reopen: "open";
20
+ readonly close: "closed";
21
+ };
22
+ readonly closed: {
23
+ readonly reopen: "open";
24
+ };
25
+ }, "open">;
26
+ export type IssueStatus = StateOf<typeof issueLifecycle>;
27
+ export type IssueEvent = EventOf<typeof issueLifecycle>;
28
+ export type AllowedIssueTransition = Extract<TransitionDecision<typeof issueLifecycle, IssueStatus, IssueEvent>, {
29
+ readonly kind: 'allowed';
30
+ }>;
@@ -0,0 +1,11 @@
1
+ import { stateMachine, } from '@astrale-os/sdk/state';
2
+ export const issueLifecycle = stateMachine({
3
+ initial: 'open',
4
+ transitions: {
5
+ open: { accept: 'accepted', defer: 'deferred', close: 'closed' },
6
+ accepted: { resolve: 'resolved', defer: 'deferred', close: 'closed' },
7
+ deferred: { reopen: 'open', accept: 'accepted', close: 'closed' },
8
+ resolved: { reopen: 'open', close: 'closed' },
9
+ closed: { reopen: 'open' },
10
+ },
11
+ });
@@ -20,15 +20,47 @@ export declare const Comment: import("@astrale-os/sdk/schema").NodeClass<{
20
20
  }, "kernel.astrale.ai:class.Node", readonly import("@astrale-os/sdk/schema").AnyResolvedClass[], never, never, never, never, never, never>, ...never[]], import("@astrale-os/sdk/schema").PropertyProjection<string | number | boolean | import("@astrale-os/sdk/schema").Array | import("@astrale-os/sdk/schema").Object | null, true, "createdAt", "kernel.astrale.ai:class.Timestamped.property.createdAt"> | import("@astrale-os/sdk/schema").PropertyProjection<string | number | boolean | import("@astrale-os/sdk/schema").Array | import("@astrale-os/sdk/schema").Object | null, true, "updatedAt", "kernel.astrale.ai:class.Timestamped.property.updatedAt">, never, never, import("@astrale-os/sdk/schema").PropertyProjection<string | number | boolean | import("@astrale-os/sdk/schema").Array | import("@astrale-os/sdk/schema").Object | null, true, "createdAt", "kernel.astrale.ai:class.Timestamped.property.createdAt"> | import("@astrale-os/sdk/schema").PropertyProjection<string | number | boolean | import("@astrale-os/sdk/schema").Array | import("@astrale-os/sdk/schema").Object | null, true, "updatedAt", "kernel.astrale.ai:class.Timestamped.property.updatedAt">, never, never>];
21
21
  readonly properties: {
22
22
  readonly body: import("@astrale-os/sdk/schema").AuthoredPropertyProjection<string, string, true, "body", "self">;
23
+ readonly authorId: import("@astrale-os/sdk/schema").AuthoredPropertyProjection<string, string, true, "authorId", "self">;
23
24
  };
24
- readonly methods: Readonly<Record<never, never>>;
25
- readonly effectiveProperties: import("@astrale-os/sdk/schema").AuthoredPropertyProjection<string, string, true, "body", "self"> | (import("@astrale-os/sdk/schema").ResolvedProperty<import("@astrale-os/sdk/schema").Value, true> & {
25
+ readonly methods: {
26
+ readonly edit: import("@astrale-os/sdk/schema").Method<import("@astrale-os/sdk/schema").CallableProjection<{
27
+ body: string;
28
+ }, {
29
+ readonly mode: 'value';
30
+ readonly value: {
31
+ id: string;
32
+ body: string;
33
+ };
34
+ }, "authorized", false, "default">>;
35
+ readonly delete: import("@astrale-os/sdk/schema").Method<import("@astrale-os/sdk/schema").CallableProjection<Record<string, never>, {
36
+ readonly mode: 'value';
37
+ readonly value: {
38
+ commentId: string;
39
+ deleted: true;
40
+ };
41
+ }, "authorized", false, "default">>;
42
+ };
43
+ readonly effectiveProperties: (import("@astrale-os/sdk/schema").AuthoredPropertyProjection<string, string, true, "authorId", "self"> | import("@astrale-os/sdk/schema").AuthoredPropertyProjection<string, string, true, "body", "self">) | (import("@astrale-os/sdk/schema").ResolvedProperty<import("@astrale-os/sdk/schema").Value, true> & {
26
44
  readonly name: "createdAt";
27
45
  readonly key: "kernel.astrale.ai:class.Timestamped.property.createdAt";
28
46
  }) | (import("@astrale-os/sdk/schema").ResolvedProperty<import("@astrale-os/sdk/schema").Value, true> & {
29
47
  readonly name: "updatedAt";
30
48
  readonly key: "kernel.astrale.ai:class.Timestamped.property.updatedAt";
31
49
  });
32
- readonly effectiveInstanceMethods: never;
50
+ readonly effectiveInstanceMethods: import("@astrale-os/sdk/schema").AuthoredMethodProjection<import("@astrale-os/sdk/schema").Method<import("@astrale-os/sdk/schema").CallableProjection<Record<string, never>, {
51
+ readonly mode: 'value';
52
+ readonly value: {
53
+ commentId: string;
54
+ deleted: true;
55
+ };
56
+ }, "authorized", false, "default">>, "delete", "self"> | import("@astrale-os/sdk/schema").AuthoredMethodProjection<import("@astrale-os/sdk/schema").Method<import("@astrale-os/sdk/schema").CallableProjection<{
57
+ body: string;
58
+ }, {
59
+ readonly mode: 'value';
60
+ readonly value: {
61
+ id: string;
62
+ body: string;
63
+ };
64
+ }, "authorized", false, "default">>, "edit", "self">;
33
65
  readonly effectiveStaticMethods: never;
34
66
  }>;
@@ -1,7 +1,16 @@
1
- import { K, nodeClass } from '@astrale-os/sdk/schema';
1
+ import { K, nodeClass, property } from '@astrale-os/sdk/schema';
2
2
  import { z } from 'zod';
3
+ import { nodeIdValue } from '../value/index.js';
4
+ import { ContributeToComment } from './contribute-to-comment-policy.js';
5
+ import { deleteCommentMethod, editCommentMethod } from './methods.js';
3
6
  export const Comment = nodeClass({
4
7
  description: 'One authored discussion entry attached to an Issue.',
8
+ icon: 'message-square',
5
9
  extends: [K.classes.Timestamped],
6
- properties: { body: z.string().min(1).max(50_000) },
10
+ properties: {
11
+ body: z.string().min(1).max(50_000),
12
+ authorId: property(nodeIdValue, { visibility: 'private' }),
13
+ },
14
+ methods: { edit: editCommentMethod, delete: deleteCommentMethod },
15
+ policies: { read: () => ContributeToComment },
7
16
  });
@@ -0,0 +1 @@
1
+ export declare const ContributeToComment: import("@astrale-os/sdk/schema").Policy;
@@ -0,0 +1,12 @@
1
+ import { policy } from '@astrale-os/sdk/schema';
2
+ import { Issue, project_contains_issue } from '../issue/index.js';
3
+ import { Project, project_has_member, project_owned_by } from '../project/index.js';
4
+ import { issue_has_comment } from './relationships.js';
5
+ export const ContributeToComment = policy({
6
+ description: 'The caller owns or belongs to the Project containing this Comment.',
7
+ match: ({ allOf, anyOf, edge, exists, object, subject }) => exists(({ node }) => {
8
+ const project = node(() => Project);
9
+ const issue = node(() => Issue);
10
+ return allOf(anyOf(edge({ source: subject, class: () => project_owned_by, target: project }), edge({ source: subject, class: () => project_has_member, target: project })), edge({ source: project, class: () => project_contains_issue, target: issue }), edge({ source: issue, class: () => issue_has_comment, target: object }));
11
+ }),
12
+ });
@@ -0,0 +1 @@
1
+ export declare const EditOwnComment: import("@astrale-os/sdk/schema").Policy;
@@ -0,0 +1,6 @@
1
+ import { policy } from '@astrale-os/sdk/schema';
2
+ import { comment_authored_by } from './relationships.js';
3
+ export const EditOwnComment = policy({
4
+ description: 'The caller is the immutable author of this Comment.',
5
+ match: ({ edge, object, subject }) => edge({ source: subject, class: () => comment_authored_by, target: object }),
6
+ });
@@ -1,2 +1,5 @@
1
1
  export { Comment } from './class.js';
2
+ export { ContributeToComment } from './contribute-to-comment-policy.js';
3
+ export { EditOwnComment } from './edit-own-comment-policy.js';
2
4
  export { comment_authored_by, issue_has_comment } from './relationships.js';
5
+ export { TraverseCommentRelationship } from './traverse-comment-relationship-policy.js';
@@ -1,2 +1,5 @@
1
1
  export { Comment } from './class.js';
2
+ export { ContributeToComment } from './contribute-to-comment-policy.js';
3
+ export { EditOwnComment } from './edit-own-comment-policy.js';
2
4
  export { comment_authored_by, issue_has_comment } from './relationships.js';
5
+ export { TraverseCommentRelationship } from './traverse-comment-relationship-policy.js';
@@ -0,0 +1,18 @@
1
+ import { method } from '@astrale-os/sdk/schema';
2
+ import { z } from 'zod';
3
+ import { commentValue, nodeIdValue } from '../value/index.js';
4
+ import { EditOwnComment } from './edit-own-comment-policy.js';
5
+ export const editCommentMethod = method({
6
+ description: 'Edit this Comment as its author.',
7
+ auth: 'authorized',
8
+ policy: ({ check, self }) => check(EditOwnComment, self),
9
+ input: z.strictObject({ body: z.string().min(1).max(50_000) }),
10
+ output: commentValue,
11
+ });
12
+ export const deleteCommentMethod = method({
13
+ description: 'Delete this Comment as its author.',
14
+ auth: 'authorized',
15
+ policy: ({ check, self }) => check(EditOwnComment, self),
16
+ input: z.strictObject({}),
17
+ output: z.strictObject({ commentId: nodeIdValue, deleted: z.literal(true) }),
18
+ });
@@ -20,12 +20,12 @@ export declare const comment_authored_by: import("@astrale-os/sdk/schema").Direc
20
20
  readonly extends: readonly [];
21
21
  readonly properties: never;
22
22
  readonly source: {
23
- readonly as: "comment";
24
- readonly outgoing: "1";
23
+ readonly as: "author";
24
+ readonly outgoing: "0..*";
25
25
  };
26
26
  readonly target: {
27
- readonly as: "author";
28
- readonly incoming: "0..*";
27
+ readonly as: "comment";
28
+ readonly incoming: "1";
29
29
  };
30
30
  readonly constraints: Record<never, never>;
31
31
  readonly effectiveProperties: never;
@@ -1,11 +1,16 @@
1
1
  import { K, edgeClass } from '@astrale-os/sdk/schema';
2
- import { Issue } from '#schema/issue';
2
+ import { Issue, TraverseIssueComment } from '../issue/index.js';
3
3
  import { Comment } from './class.js';
4
+ import { TraverseCommentRelationship } from './traverse-comment-relationship-policy.js';
4
5
  export const issue_has_comment = edgeClass.directed({
5
- source: { as: 'issue', accepts: [Issue], outgoing: '0..*' },
6
- target: { as: 'comment', accepts: [Comment], incoming: '1' },
6
+ description: 'One Issue contains one Comment.',
7
+ source: { as: 'issue', accepts: [() => Issue], outgoing: '0..*' },
8
+ target: { as: 'comment', accepts: [() => Comment], incoming: '1' },
9
+ policies: { traverse: () => TraverseIssueComment },
7
10
  });
8
11
  export const comment_authored_by = edgeClass.directed({
9
- source: { as: 'comment', accepts: [Comment], outgoing: '1' },
10
- target: { as: 'author', accepts: [K.classes.Identity], incoming: '0..*' },
12
+ description: 'The immutable author of one Comment.',
13
+ source: { as: 'author', accepts: [K.classes.Identity], outgoing: '0..*' },
14
+ target: { as: 'comment', accepts: [() => Comment], incoming: '1' },
15
+ policies: { traverse: () => TraverseCommentRelationship },
11
16
  });
@@ -0,0 +1,2 @@
1
+ /** Comment relationships disclose only inside the containing Project. */
2
+ export declare const TraverseCommentRelationship: import("@astrale-os/sdk/schema").Policy;
@@ -0,0 +1,17 @@
1
+ import { policy } from '@astrale-os/sdk/schema';
2
+ import { Issue, project_contains_issue } from '../issue/index.js';
3
+ import { Project, project_has_member, project_owned_by } from '../project/index.js';
4
+ import { comment_authored_by, issue_has_comment } from './relationships.js';
5
+ /** Comment relationships disclose only inside the containing Project. */
6
+ export const TraverseCommentRelationship = policy({
7
+ description: 'The caller owns or belongs to the Project containing the source Comment.',
8
+ match: ({ allOf, anyOf, edge, exists, source, subject, target }) => anyOf(exists(({ node }) => {
9
+ const issue = node(() => Issue);
10
+ const project = node(() => Project);
11
+ return allOf(edge({ source, class: () => comment_authored_by, target }), edge({ source: issue, class: () => issue_has_comment, target }), edge({ source: project, class: () => project_contains_issue, target: issue }), edge({ source: subject, class: () => project_owned_by, target: project }));
12
+ }), exists(({ node }) => {
13
+ const issue = node(() => Issue);
14
+ const project = node(() => Project);
15
+ return allOf(edge({ source, class: () => comment_authored_by, target }), edge({ source: issue, class: () => issue_has_comment, target }), edge({ source: project, class: () => project_contains_issue, target: issue }), edge({ source: subject, class: () => project_has_member, target: project }));
16
+ })),
17
+ });
@@ -1,7 +1,6 @@
1
- export { schema } from './application/index.js';
2
- export type { IssuesDomain, IssuesSchema } from './application/index.js';
3
- export { Command, command_requested_by, command_targets_primary } from './command/index.js';
1
+ export { schema } from './schema.js';
2
+ export type { IssuesDomain, IssuesSchema } from './schema.js';
4
3
  export { Comment, comment_authored_by, issue_has_comment } from './comment/index.js';
5
- export { Issue, issue_assigned_to, issue_blocks, issue_duplicates, issue_relates_to, issue_reported_by, issue_subtask_of, tracker_contains_issue, } from './issue/index.js';
6
- export { Tag, issue_tagged_with, tracker_contains_tag } from './tag/index.js';
7
- export { Tracker, tracker_owned_by } from './tracker/index.js';
4
+ export { Issue, issue_assigned_to, issue_reported_by, issue_subtask_of, project_contains_issue, } from './issue/index.js';
5
+ export { Project, project_has_member, project_owned_by } from './project/index.js';
6
+ export { Tag, issue_tagged_with, project_contains_tag } from './tag/index.js';
@@ -1,6 +1,5 @@
1
- export { schema } from './application/index.js';
2
- export { Command, command_requested_by, command_targets_primary } from './command/index.js';
1
+ export { schema } from './schema.js';
3
2
  export { Comment, comment_authored_by, issue_has_comment } from './comment/index.js';
4
- export { Issue, issue_assigned_to, issue_blocks, issue_duplicates, issue_relates_to, issue_reported_by, issue_subtask_of, tracker_contains_issue, } from './issue/index.js';
5
- export { Tag, issue_tagged_with, tracker_contains_tag } from './tag/index.js';
6
- export { Tracker, tracker_owned_by } from './tracker/index.js';
3
+ export { Issue, issue_assigned_to, issue_reported_by, issue_subtask_of, project_contains_issue, } from './issue/index.js';
4
+ export { Project, project_has_member, project_owned_by } from './project/index.js';
5
+ export { Tag, issue_tagged_with, project_contains_tag } from './tag/index.js';